#ifndef _CIC_COMMON_H_
#define _CIC_COMMON_H_

typedef unsigned char u8;
typedef unsigned short u16;

struct u4
{
	u8 zero		: 4;
	u8 value	: 4;
 
	u4(){}
	u4(u8 _value) {
		zero = 0;
		value = _value;
	}
	const u4 operator+(const u4& b) { return value + b.value; }
	u4& operator+=(const u4& b) { value += b.value; return *this; }
	u4 operator|(const u4& b) { return value | b.value; }
	u4 operator&(const u4& b) { return value & b.value; }
	bool operator==(const u4& b) { return value == b.value; }

	bool check_overflow(const u8 operand) const { return operand > (0xf - value); }
};

struct u6
{
	u8 zero		: 2;

	struct internal {
		u8 low	: 4;
		u8 high	: 2;
	};

	union {
		u8 value: 6;
		internal i;
	};

	u6(){}
	u6(u8 _value) {
		zero = 0;
		value = _value;
	}
	u6 operator+(u6& b) { return value + b.value; }
	u6& operator+=(const u6& b) { value += b.value; return *this; }
	bool operator==(u6& b) { return value == b.value; }

	void set_low(const u8 val) { i.low = val; }
	void set_high(const u8 val) { i.high = val; }
	u8 get_low() const { return i.low; }
	u8 get_high() const { return i.high; }

	bool increment_low() { i.low++; return i.low == 0; }
	bool decrement_low() { i.low--; return i.low == 0xf; }
};

struct u10
{
	u16 zero	: 6;

	struct internal {
		u16 offset	: 7;
		u16 segment	: 3;
	};

	union {
		u16 value	: 10;
		internal i;
	};

	u10(){}
	u10(u16 _value) {
		zero = 0;
		value = _value;
	}
	u10 operator+(u10& b) { return value + b.value; }
	u10& operator+=(const u10& b) { value += b.value; return *this; }
	bool operator==(u10& b) { return value == b.value; }
};

#endif // _CIC_COMMON_H_
